# -*- coding: utf-8 -*-
'''
# file name:内置函数.PY
# author： azj
# datetime： 2022/7/11 10:25 
# ide： PyCharm
'''

'''
常用的内置函数 高级点的内置函数

# 一、filter




'''


# 需求 ： 把列表表中大于5的元素过滤出来 【1，,3，,5，-1，56，33，,2，8，,10】---> [56，33，8,10]

# 方法一 使用传统方法 使用for循环过滤 99%的人都会
def get_new_list(data_list, mark=5):
    new_list = []
    for value in data_list:
        if value > mark:
            new_list.append(value)
    return new_list


if __name__ == '__main__':
    data_list = [1, 3, 5, -1, 56, 33, 2, 8, 10]
    print(get_new_list(data_list))  # [56, 33, 8, 10]

# 方法二（强烈推荐！！！）：使用lambda匿名函数配合filter实现该需求，最优雅的方法使用filter 使用lambda 强烈推荐！！！
data_list2 = [1, 3, 5, -1, 56, 33, 2, 8, 10]
print(filter(lambda x: x > 5,
             data_list2))  # <filter object at 0x7f810802f748> filter(function or None, iterable) --> filter object
# 直接调用filter方法会返回filter对象 想看到值 要么用for循环要么转换成列表 所以在filter外层加一个list(filter对象)
print(list(filter(lambda x: x > 5, data_list2)))  # [56, 33, 8, 10]


# 方法三、使用 filter函数处理 不使用lambda

def filter_test():
    def f(x):
        if x > 5:
            return True  # 为True 时对 [1,2,3,4] 中的所有元素依次进行f操
            # return None # 为None 时不对 [1,2,3,4] 中的所有元素依次进行f操
        return False

    return filter(f, [1, 3, 5, -1, 56, 33, 2, 8, 10])  # 对  [1, 3, 5, -1, 56, 33, 2, 8, 10]中的所有元素依次进行f操作


if __name__ == '__main__':
    print(list(filter_test()))  # 为True 时 的结果[56, 33, 8, 10]
    # print(list(filter_test())) # 为None 时 的结果[[]

# 2 、map （如何映射，【要映射的对象1，要映射的对象1，。。。。。】） 映射

# 需求：把两个列表中 每个元素相加生成新的列表 两个列表的个数相同 【1,2,3,4】 【5,6,7,8】---》【6,8,10,12】

# 方法一、使用for循环完成两个列表数据的相加 99% 的人想到的方法
'''
思路： 循环第一个列表 第一个的值和索引 在循环第二个 根据第一个的索引娶到第二个的值 两值相加后 追加到列表里面 在循环二需要break 就可以了 
上代码
'''


def list_add_test(list1, list2):
    new_list = []
    for i, value in enumerate(list1):
        for j in list2:
            new_list.append(value + list2[i])
            break
    return new_list


if __name__ == '__main__':
    list1 = [1, 2, 3, 4]
    list2 = [5, 6, 7, 8]
    print(list_add_test(list1, list2))  # [6, 8, 10, 12]


# 方法二 、 对方法一的优化 不需要对 list2 进行循环
def list_add_test2(list1, list2):
    new_list = []
    for i, value in enumerate(list1):
        new_list.append(value + list2[i])
    return new_list


if __name__ == '__main__':
    list1 = [1, 2, 3, 4]
    list2 = [5, 6, 7, 8]
    print(list_add_test2(list1, list2))  # [6, 8, 10, 12]


# 方法三、使用map函数实现两个列表函数的相加
def map_test():
    # help(map) # map(func, *iterables) --> map object
    return list(map(lambda x, y: x + y, [1, 2, 3, 4], [5, 6, 7, 8]))


if __name__ == '__main__':
    print(map_test())


# 方法四  不使用lambda 使用f函数map完成列表值相加
def map_test2():
    list1 = [1, 2, 3, 4]
    list2 = [5, 6, 7, 8]
    list3 = [9, 10, 11, 12]

    def f(x, y, z):
        return x + y + z

    # help(map) # map(func, *iterables) --> map object
    return list(map(f, list1, list2, list3))


if __name__ == '__main__':
    print('f函数', map_test2())  # f函数 [15, 18, 21, 24]

# reduce 累加功能
from functools import reduce

print(dir(reduce))
'''
reduce(function, sequence[, initial]) -> value
For example, reduce(lambda x, y: x+y, [1, 2, 3, 4, 5]) calculates ((((1+2)+3)+4)+5)
'''

# 需求 统计列表的值 [1, 2, 3, 4, 5]


# 方法一 、使用内置函数sum进行统计
print(sum([1, 2, 3, 4, 5]))  # 15

# 方法二、使用for循环进行统计
result = 0
for i in [1, 2, 3, 4, 5]:
    result += i

print(result)  # 15


# 方法三： 使用reduce内置函数配合lambda 进行对列表求和计算 入参x是函数的返回值 y是下一个数

def reduce_test():
    return reduce(lambda x, y: x + y, [1, 2, 3, 4, 5])  # reduce(function, sequence[, initial]) -> value 返回的是值


if __name__ == '__main__':
    print(reduce_test())  # 15

# zip函数

'''
    print(help(zip))
    zip(iter1 [,iter2 [...]]) --> zip object
    
    Return a zip object whose .__next__() method returns a tuple where
    the i-th element comes from the i-th iterable argument.  The .__next__()
    method continues until the shortest iterable in the argument sequence
    is exhausted and then it raises StopIteration.
zip函数用法：
“zip函数是Python的内置函数,它用于将可迭代的对象作为参数,将对象中对应的元素打包成一个个元组,
然后返回由这些元组组成的对象(即对多个序列进行并行迭代)。
如果各个迭代器元素个数不一致,zip()函数则在最短序列“用完”时就会停止。”

举例：zip('zxcv',range(4),range(4))----> [(z,0,0), (x,1,1),(c,2,2)]
'''


def zip_test():
    return zip('zxcv', range(1, 5))


if __name__ == '__main__':
    print(list(zip_test()))  # [('z', 1), ('x', 2), ('c', 3), ('v', 4)]
